package com.eastfair.projectcore.controller;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.eastfair.annotation.annotation.log.SysLog;
import com.eastfair.auth.api.AuthServiceFeign;
import com.eastfair.constant.BusinessConstant;
import com.eastfair.core.context.ContextUtil;
import com.eastfair.point.business.auth.BusinLoadUserPermissOfRolePoint;
import com.eastfair.point.orderbusiness.OrderUserPoint;
import com.eastfair.point.pointlog.LogPoint;
import com.eastfair.projectcore.dto.*;
import com.eastfair.projectcore.entity.Menu;
import com.eastfair.projectcore.enumeration.MenuAffiliationEnum;
import com.eastfair.projectcore.enumeration.MenuSceneEnum;
import com.eastfair.projectcore.service.MenuService;
import com.eastfair.projectcore.vo.MenuVO;
import com.eastfair.log.point.PointUtil;
import com.eastfair.point.UserLoginPoint;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.eastfair.boot.controller.SuperController;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.eastfair.echo.core.EchoService;
import com.eastfair.core.base.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import static com.eastfair.core.base.R.SUCCESS_CODE;


/**
 * <p>
 * 前端控制器
 * 菜单
 * </p>
 *
 * @author ligang
 * @date 2021-07-22
 */
@Slf4j
@Validated
@RestController
@RequestMapping("/menu")
@Api(value = "Menu", tags = "菜单")
public class MenuController extends SuperController<MenuService, Long, Menu, MenuPageQuery, MenuSaveDTO, MenuUpdateDTO> {

    @Autowired
    private EchoService echoService;
    @Autowired
    PointUtil pointUtil;

    @Autowired
    AuthServiceFeign authServiceFeign;

    @Value("${com.eastfair.projectId}")
    private Long commonProjectId;

    @Override
    public void handlerResult(IPage<Menu> page) {
        // 想让返回值实现自动回显，请将此行代码打开
        // echoService.action(page);
    }

    /**
     * Excel导入后的操作
     *
     * @param list
     */
    @Override
    public R<Boolean> handlerImport(List<Map<String, String>> list) {
        List<Menu> menuList = list.stream().map((map) -> {
            Menu menu = Menu.builder().build();
            //TODO 请在这里完成转换
            return menu;
        }).collect(Collectors.toList());

        return R.success(baseService.saveBatch(menuList));
    }


    /**
     * 删除,并删除旗下所有子菜单
     *
     * @param ids 集合
     */
    @ApiOperation(value = "删除", notes = "删除")
    @DeleteMapping("/del")
    public R del(@RequestBody List<Long> ids) {
        if (ids != null && !ids.isEmpty()) {
            for (Long id : ids) {
                baseService.del(id);
            }
        }
        return R.success();
    }


    /**
     * 创建菜单节点
     *
     * @param menuDTO 菜单实体
     */
    @ApiOperation(value = "创建菜单节点", notes = "创建菜单节点")
    @PostMapping("/createMenu")
    public R createMenu(@RequestBody @Validated({MenuDTO.createMenu.class}) MenuDTO menuDTO) {
        if (menuDTO.getParentId() == null) {
            QueryWrapper<Menu> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(Menu::getAffiliation, menuDTO.getAffiliation());
            queryWrapper.lambda().eq(Menu::getScene, menuDTO.getScene());
            queryWrapper.lambda().eq(Menu::getParentId, BusinessConstant.parentId);
            queryWrapper.lambda().eq(Menu::getIsDeleted, BusinessConstant.DELETE_NO);
            //根据场景追加父级id
            Menu menu = baseService.getOne(queryWrapper);
            menuDTO.setParentId(menu.getParentId());
        }
        MenuSaveDTO menuSaveDTO = new MenuSaveDTO();
        BeanUtils.copyProperties(menuDTO, menuSaveDTO);
        R<Menu> r = baseService.createMenu(menuSaveDTO);
        return r;
    }


    /**
     * 初始化顶级菜单
     */
    @ApiOperation(value = "初始化顶级菜单", notes = "初始化顶级菜单")
    @GetMapping("/initMenuParent")
    public R initMenuParent() {
        baseService.initMenuParent();
        return R.success();
    }

    /**
     * 修改菜单信息
     *
     * @param menuUpdateDTO 菜单更新实体
     */
    @ApiOperation(value = "修改菜单信息", notes = "修改菜单信息")
    @PutMapping("/updMenu")
    public R updMenu(@RequestBody MenuUpdateDTO menuUpdateDTO) {
        return baseService.updateMenu(menuUpdateDTO);
    }


    /**
     * 置顶
     *
     * @param id 菜单id
     */
    @ApiOperation(value = "置顶", notes = "置顶")
    @PostMapping("/sortTop")
    public R sortTop(@RequestBody Long id) {
        baseService.sortTop(id);
        return R.success();
    }


    /**
     * 查询菜单信息和全部子信息
     *
     * @param menuDTO 菜单id
     * @return 查询结果
     */
    @ApiOperation(value = "查询菜单信息和全部子信息", notes = "查询菜单信息和全部子信息")
    @PostMapping("/findAllById")
    public R<List<MenuVO>> findAllById(@RequestBody MenuDTO menuDTO) {
//        if (menuDTO != null && menuDTO.getAffiliation()==null ) {
//            menuDTO.setAffiliation(MenuAffiliationEnum.get(ContextUtil.getSystemScene()));
//        }
        if (menuDTO != null && menuDTO.getScene() == null) {
            menuDTO.setScene(MenuSceneEnum.MANAGE);
        }
        List<Long> menuIds = baseService.queryId(menuDTO);
        List<MenuVO> result = new ArrayList<>();
        List<Long> myMenuIds = null;
        R<List<Long>> listR = authServiceFeign.queryMenuIdOfUser(ContextUtil.getUserId());
        if (SUCCESS_CODE == listR.getCode()) {
            myMenuIds = listR.getData();
        }
        if (myMenuIds == null || myMenuIds.isEmpty()) {
            //用户没有菜单，导致查不到属于自己的菜单
            return success(null);
        }
        for (Long menuid : menuIds) {
            //查询全部菜单
            MenuVO menuVO = baseService.findAllById(menuid, myMenuIds);
            if (menuVO != null) {
                result.add(menuVO);
            }
        }
        return success(result);
    }

    /**
     * 查询菜单信息和全部子信息
     *
     * @param menuDTO 菜单id
     * @return 查询结果
     */
    @ApiOperation(value = "查询菜单信息和全部子信息", notes = "查询菜单信息和全部子信息")
    @PostMapping("/findAllByIdOfRoot")
    public R<List<MenuVO>> findAllByIdOfRoot(@RequestBody MenuDTO menuDTO) {
        if (menuDTO != null) {
            if (menuDTO.getAffiliation() == null) {
                //查全部
                menuDTO.setAffiliationList(Arrays.asList(MenuAffiliationEnum.values()));
            } else {
                menuDTO.setAffiliationList(Arrays.asList(menuDTO.getAffiliation()));
            }
            if (menuDTO.getScene() == null) {
                menuDTO.setSceneList(Arrays.asList(MenuSceneEnum.values()));
            }
        }
        List<Long> menuIds = new ArrayList<>();
        if (menuDTO.getAffiliationList() != null && !menuDTO.getAffiliationList().isEmpty()) {
            for (MenuAffiliationEnum menuAffiliationEnum : menuDTO.getAffiliationList()) {
                menuDTO.setAffiliation(menuAffiliationEnum);
                menuIds.addAll(baseService.queryId(menuDTO));
            }
        }
        List<MenuVO> result = new ArrayList<>();
        for (Long menuid : menuIds) {
            //查询全部菜单
            MenuVO menuVO = baseService.findAllById(menuid, null);
            result.add(menuVO);
        }
        return success(result);
    }

    /**
     * 根据场景查询菜单全部子信息
     *
     * @return 查询结果
     */
    @ApiOperation(value = "根据场景查询菜单全部子信息", notes = "根据场景查询菜单全部子信息")
    @PostMapping("/findAllChildOfparentId")
    public R<List<MenuVO>> findAllChildOfparentId(@RequestBody MenuDTO menuDTO) {
        List<Long> menuIds = baseService.queryId(menuDTO);
        List<MenuVO> result = new ArrayList<>();
        List<Long> myMenuIds = null;
        R<List<Long>> listR = authServiceFeign.queryMenuIdOfUser(ContextUtil.getUserId());
        if (SUCCESS_CODE == listR.getCode()) {
            myMenuIds = listR.getData();
        }
        for (Long menuid : menuIds) {
            //查询全部菜单
            MenuVO menuVO = baseService.findAllById(menuid, myMenuIds);
            result.add(menuVO);
        }
        return success(result);
    }


    /**
     * 查询菜单信息和全部子信息
     *
     * @param menuDTO 菜单实体
     * @return 查询结果
     */
    @ApiOperation(value = "通过子菜单查询菜单信息和全部子信息", notes = "通过子菜单查询菜单信息和全部子信息")
    @PostMapping("/findAllByChildId")
    public R<List<MenuVO>> findAllByChildId(@RequestBody MenuDTO menuDTO) {
        //根据场景查菜单
        List<Long> menuIds = baseService.queryId(menuDTO);
        List<Long> ids = new ArrayList<>();
        if (menuDTO != null && menuDTO.getMenuIds() != null) {
            ids = menuDTO.getMenuIds();
        }
        if (menuIds != null && !menuIds.isEmpty()) {
            ids.removeAll(menuIds);
        }
        return success(baseService.findAllByChildId(ids));
    }

    /**
     * 查询左侧菜单信息(包含菜单，目录)
     *
     * @return 查询结果
     */
    @ApiOperation(value = "查询菜单信息和全部子信息", notes = "查询菜单信息和全部子信息")
    @PostMapping("/findAllByChildIdNoButton")
    @SysLog("查询菜单信息和全部子信息")
    public R<List<MenuVO>> findAllByChildIdNoButton(@RequestBody MenuDTO menuDTO) {
//        List<Long> menuIds = baseService.queryId(menuDTO);
//        if (menuDTO == null && menuDTO.getMenuIds() == null && menuDTO.getAffiliation() == null && menuDTO.getScene() == null && menuIds != null && !menuIds.isEmpty()) {
//            List<MenuVO> result = new ArrayList<>();
//            for (Long menuid : menuIds) {
//                //查询全部菜单
//                MenuVO menuVO = baseService.findAllByIdNoButton(menuid);
//                result.add(menuVO);
//            }
//            return success(result);
//        } else {
//            if (menuIds == null || menuIds.isEmpty()) {
//                return success(null);
//            }
//            //查询全部菜单
//            MenuVO menuVO = baseService.findAllByIdNoButton(menuIds.get(0));
//            return success(menuVO.getChildVoList());
//        }
        //根据场景查菜单
        List<Long> menuIds = baseService.queryId(menuDTO);
        return success(baseService.findAllByChildIdNoButton(menuIds, menuDTO.getMenuIds()));


    }


    /**
     * 查询左侧菜单信息(包含菜单，目录)
     *
     * @return 查询结果
     */
    @ApiOperation(value = "查询菜单信息和全部子信息", notes = "查询菜单信息和全部子信息")
    @PostMapping("/findAllByIdNoButton")
    public R<MenuVO> findAllByIdNoButton(@RequestBody MenuDTO menuDTO) {
        Long id = null;
        List<Long> menuIds = baseService.queryId(menuDTO);
        if (menuIds != null && !menuIds.isEmpty()) {
            id = menuIds.get(0);
        }
        return success(baseService.findAllByIdNoButton(id));
    }

    /**
     * 查询按钮权限信息集合
     *
     * @return 查询结果
     */
    @ApiOperation(value = "查询按钮权限信息集合", notes = "查询按钮权限信息集合")
    @GetMapping("/findButtonPermission")
    public R<List<String>> findButtonPermission() {
        return success(baseService.findButtonPermission());
    }


    /**
     * 查询菜单的权限标识
     *
     * @param menuDTO 菜单实体
     * @return 查询结果
     */
    @ApiOperation(value = "查询菜单的权限标识", notes = "查询菜单的权限标识")
    @PostMapping("/findPermissionAllByChildId")
    public R<List<String>> findPermissionAllByChildId(@RequestBody MenuDTO menuDTO) {
        //根据场景查菜单
        List<Long> menuIds = baseService.queryId(menuDTO);
        List<Long> ids = new ArrayList<>();
        if (menuDTO != null && menuDTO.getMenuIds() != null) {
            ids = menuDTO.getMenuIds();
        }
        if (menuIds != null && !menuIds.isEmpty()) {
            ids.removeAll(menuIds);
        }
        return success(baseService.findPermissionAllByChildId(ids));
    }


    /**
     * 查询菜单的接口权限标识
     *
     * @param menuDTO 菜单实体
     * @return 查询结果
     */
    @ApiOperation(value = "查询菜单的接口权限标识", notes = "查询菜单的接口权限标识")
    @PostMapping("/findInterfaceAllByChildId")
    public R<List<String>> findInterfaceAllByChildId(@RequestBody MenuDTO menuDTO) {
        //根据场景查菜单
        List<Long> menuIds = baseService.queryId(menuDTO);
        List<Long> ids = new ArrayList<>();
        if (menuDTO != null && menuDTO.getMenuIds() != null) {
            ids = menuDTO.getMenuIds();
        }
//        if (menuIds != null && !menuIds.isEmpty()) {
//            ids.removeAll(menuIds);
//        }
        return success(baseService.findInterfaceAllByChildId(ids));
    }


    /**
     * 查询全部菜单信息
     *
     * @return 查询结果
     */
    @ApiOperation(value = "查询全部菜单信息", notes = "查询全部菜单信息")
    @GetMapping("/queryAllMenuId")
    public R<List<Long>> queryAllMenuId() {
        QueryWrapper<Menu> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(Menu::getIsDeleted, BusinessConstant.NO);
        List<Menu> menuList = baseService.list(queryWrapper);
        if (menuList != null && !menuList.isEmpty()) {
            return success(menuList.stream().map(Menu::getId).collect(Collectors.toList()));
        }
        return success(null);
    }


    /**
     * 查询最子集菜单信息
     *
     * @return 查询结果
     */
    @ApiOperation(value = "查询最子集菜单信息(前端要)", notes = "查询最子集菜单信息")
    @PostMapping("/queryBestChildMenuId")
    public R<List<Long>> queryBestChildMenuId(@RequestBody List<Long> menuIds) {
        List<Long> bestChildIds = new ArrayList<>();
        QueryWrapper<Menu> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(Menu::getIsDeleted, BusinessConstant.NO);
        queryWrapper.lambda().in(Menu::getId, menuIds);
        List<Menu> menuList = baseService.list(queryWrapper);
        if (menuList != null && !menuList.isEmpty()) {
            for (Menu menu : menuList) {
                Long id = menu.getId();
                boolean pan = true;
                for (Menu menu2 : menuList) {
                    if (menu2.getParentId().equals(id)) {
                        pan = false;
                        break;
                    }
                }
                if (pan) {
                    bestChildIds.add(id);
                }
            }
            return success(bestChildIds);
        }
        return success(null);
    }

    /**
     * 查询菜单全部子信息
     *
     * @param id 菜单idLogAutoConfiguration
     * @return 查询结果
     */
    @ApiOperation(value = "查询菜单全部子信息", notes = "查询菜单全部子信息")
    @GetMapping("/test")
    public R test(Long id) {
//        QueryWrapper<Menu> queryWrapper = new QueryWrapper<>();
//        queryWrapper.lambda().eq(Menu::getIsDeleted, BusinessConstant.NO);
//        List<Menu> menuList =  baseService.list(queryWrapper);
//        for(Menu menu : menuList){
//            String code = menu.getCode();
//            code = code.replaceAll("%","`");
//            code = code.replaceAll("!","-");
//            code = code.replaceAll("\\*","~");
//            menu.setCode(code);
//            baseService.updateById(menu);
//
//        }

        LogPoint logPoint = new LogPoint();
        logPoint.setEmail("数据步骤1");
        logPoint.setMsg("操作记录1");
        pointUtil.addLogPointMsg(logPoint);


        OrderUserPoint orderUserPoint = new OrderUserPoint();
        orderUserPoint.setUserId(1111L);
        orderUserPoint.setOrderPointOrderId("3333阿达打发");
        pointUtil.addOrderBusinPointMsg(orderUserPoint);

        orderUserPoint = new OrderUserPoint();
        orderUserPoint.setOrderPointOrderId("3333阿达打发");
        orderUserPoint.setUserId(2222L);
        pointUtil.addOrderBusinPointMsg(orderUserPoint);

        orderUserPoint = new OrderUserPoint();
        orderUserPoint.setUserId(1111L);
        orderUserPoint.setOrderPointOrderId("3333");
        pointUtil.addOrderBusinPointMsg(orderUserPoint);

        orderUserPoint = new OrderUserPoint();
        orderUserPoint.setOrderPointOrderId("3333");
        orderUserPoint.setUserId(2222L);
        pointUtil.addOrderBusinPointMsg(orderUserPoint);

        BusinLoadUserPermissOfRolePoint businLoadUserPermissOfRolePoint = new BusinLoadUserPermissOfRolePoint();
        businLoadUserPermissOfRolePoint.setProjectId(11111L);
        businLoadUserPermissOfRolePoint.setRoleIdList(Arrays.asList(111L, 222L));
        pointUtil.addBusinPointMsg(businLoadUserPermissOfRolePoint);

        return success();
    }


    /**
     * 初始化业务系统菜单
     */
    @ApiOperation(value = "初始化业务系统菜单", notes = "初始化业务系统菜单")
    @GetMapping("/initSystemMenu")
    public R initSystemMenu() {
        ContextUtil.setProjectId(1875437499522482176L);
        baseService.initSystemMenu();
        return R.success();
    }

    /**
     * 复制菜单
     */
    @ApiOperation(value = "初始化业务系统菜单", notes = "初始化业务系统菜单")
    @PostMapping("/copyMenu")
    public R copyMenu(@RequestBody MenuDTO menuDTO) {
        Menu menu = baseService.getByIdCache(menuDTO.getId());
        MenuVO menuVO = baseService.findAllById(menuDTO.getCopyMenuId());
        baseService.copyMenu(menu, Arrays.asList(menuVO));
        return R.success();
    }


    /**
     * 查询系统所有路由
     *
     * @param menuDTO 菜单id
     * @return 查询结果
     */
    @ApiOperation(value = "查询系统所有路由", notes = "查询系统所有路由")
    @PostMapping("/findAllUrlOfRoot")
    public R<List<String>> findAllUrlOfRoot(@RequestBody MenuDTO menuDTO) {
        if (menuDTO != null) {
            if (menuDTO.getAffiliation() == null) {
                //查全部
                menuDTO.setAffiliationList(Arrays.asList(MenuAffiliationEnum.values()));
            } else {
                menuDTO.setAffiliationList(Arrays.asList(menuDTO.getAffiliation()));
            }
            if (menuDTO.getScene() == null) {
                menuDTO.setSceneList(Arrays.asList(MenuSceneEnum.values()));
            }
        }
        List<Long> menuIds = new ArrayList<>();
        if (menuDTO.getAffiliationList() != null && !menuDTO.getAffiliationList().isEmpty()) {
            for (MenuAffiliationEnum menuAffiliationEnum : menuDTO.getAffiliationList()) {
                menuDTO.setAffiliation(menuAffiliationEnum);
                menuIds.addAll(baseService.queryId(menuDTO));
            }
        }
        List<String> result = new ArrayList<>();
        for (Long menuid : menuIds) {
            //查询全部菜单
            List<String> menuUrls = baseService.findAllUrlById(menuid, null);
            if (CollectionUtil.isNotEmpty(menuUrls)) {
                result.addAll(menuUrls);
            }
        }
        return success(result);
    }



}
